package com.xk857.simpleeffect.activity;

import android.app.DatePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.loper7.date_time_picker.dialog.CardDatePickerDialog;
import com.xk857.simpleeffect.R;
import com.xk857.simpleeffect.adapter.ListFriendCollaborationAdapter;
import com.xk857.simpleeffect.adapter.ListSelectFriendAdapter;
import com.xk857.simpleeffect.domain.Result;
import com.xk857.simpleeffect.domain.entity.Business;
import com.xk857.simpleeffect.domain.param.InvitationFriendBusinessParam;
import com.xk857.simpleeffect.domain.vo.CustomerBusinessSimpleVO;
import com.xk857.simpleeffect.domain.vo.FriendListVo;
import com.xk857.simpleeffect.domain.vo.ProjectSimpleVO;
import com.xk857.simpleeffect.enums.RequestEnum;
import com.xk857.simpleeffect.utils.CalendarUtils;
import com.xk857.simpleeffect.utils.OkHttpUtils;
import com.xuexiang.xui.utils.WidgetUtils;
import com.xuexiang.xui.widget.actionbar.TitleBar;
import com.xuexiang.xui.widget.dialog.LoadingDialog;
import com.xuexiang.xui.widget.dialog.materialdialog.MaterialDialog;
import com.xuexiang.xui.widget.toast.XToast;

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import de.hdodenhof.circleimageview.CircleImageView;

public class UpdateTodoActivity extends AppCompatActivity {

    private TextView leftDateWeekText;
    private TextView leftDateText;
    private TextView rightDateWeekText;
    private TextView rightDateText;

    private Business updateBusiness;
    private TextView remindText;
    private RadioGroup radioGroup;


    private static final SimpleDateFormat canalSdf = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
    private EditText titleEdit;
    private EditText remarkEdit;
    private LinearLayout projectLayout;
    private TextView projectText;

    private List<ProjectSimpleVO> projectList;

    private Calendar startDate;
    private Calendar endDate;
    private final int[] radios = {R.id.rb_button0, R.id.rb_button1, R.id.rb_button2, R.id.rb_button3, R.id.rb_button4, R.id.rb_button5};
    private LinearLayout finishLayout;
    private TextView finishText;
    private LinearLayout remindLayout;
    private TextView iconRightImg;
    private LinearLayout addPersonLayout;
    private LinearLayout personListLayout;
    private RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        getWindow().setStatusBarColor(ContextCompat.getColor(this, R.color.white));
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        setContentView(R.layout.activity_add_todo);
        initView();
        initData();
    }

    private void initData() {
        // 根据id查询
        long id = getIntent().getLongExtra("id", -1);
        if (id == -1) {
            new MaterialDialog.Builder(this).iconRes(R.drawable.icon_info).title(R.string.info).content("请传递id到此页面").positiveText(R.string.yes).onPositive((dialog, which) -> finish()).show();
        }

        // 根据id查询待办详情
        Type type = new TypeToken<Result<Business>>() {}.getType();
        String url = OkHttpUtils.BASE_URL + "/api/v1/business/" + id;
        OkHttpUtils.getInstance().get(this, url, type, true, (Consumer<Business>) mBusiness -> {
            this.updateBusiness = mBusiness;
            // 显示时间
            Date leftDate = DateUtil.parse(updateBusiness.getStartTime(), "yyyyMMdd");
            Date rightDate = DateUtil.parse(updateBusiness.getEndTime(), "yyyyMMdd");
            startDate = CalendarUtils.formatByDate(leftDate);
            endDate = CalendarUtils.formatByDate(rightDate);

            runOnUiThread(() -> {
                leftDateText.setText(DateUtil.format(leftDate, "MM月dd日"));
                leftDateWeekText.setText(CalendarUtils.getWeek(leftDate, true));
                rightDateText.setText(DateUtil.format(rightDate, "MM月dd日"));
                rightDateWeekText.setText(CalendarUtils.getWeek(rightDate, true));

                titleEdit.setText(mBusiness.getTitle());
                remarkEdit.setText(mBusiness.getRemark());
                radioGroup.check(radios[Integer.parseInt(mBusiness.getIcon())]);
                if (StrUtil.isNotBlank(mBusiness.getEndTime()) && StrUtil.isNotBlank(mBusiness.getStartTime())) {
                    int differenceInDays = Integer.parseInt(mBusiness.getEndTime()) - Integer.parseInt(mBusiness.getStartTime());
                    if (differenceInDays == 0) {
                        iconRightImg.setText("24小时");
                    } else {
                        iconRightImg.setText(String.format(Locale.CHINA, "%d天", differenceInDays + 1));
                    }
                }


                // 设置提醒时间
                if (updateBusiness.getRemindTime() != null) {
                    if (updateBusiness.getRemindTime().getYear() == LocalDateTime.now().getYear()) {
                        remindText.setText(LocalDateTimeUtil.format(updateBusiness.getRemindTime(), "MM月dd日 HH:mm"));
                    } else {
                        remindText.setText(LocalDateTimeUtil.format(updateBusiness.getRemindTime(), DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                    }
                } else {
                    remindText.setText(R.string.no_remind);
                }
                projectText.setText(StrUtil.hasBlank(mBusiness.getProjectName()) ? "未绑定项目" : mBusiness.getProjectName());

                if (mBusiness.getStatus()) {
                    // 项目已完成，隐藏提醒时间，显示完成时间
                    remindLayout.setVisibility(View.GONE);
                    finishLayout.setVisibility(View.VISIBLE);
                    if (mBusiness.getFinishTime().getYear() == LocalDateTime.now().getYear()) {
                        finishText.setText(LocalDateTimeUtil.format(mBusiness.getFinishTime(), "MM月dd日 HH:mm"));
                    } else {
                        finishText.setText(LocalDateTimeUtil.format(mBusiness.getFinishTime(), DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                    }
                }
                if (mBusiness.getProjectId() != null) {
                    // 如果事项绑定项目，可添加协作人，并显示协作成员列表
                    addPersonLayout.setVisibility(View.VISIBLE);
                    personListLayout.setVisibility(View.VISIBLE);
                    initPersonList();
                    addPersonLayout.setOnClickListener(v -> showAddPersonDialog(mBusiness.getProjectId()));
                }
            });
        });

        // 监听单选按钮
        radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
            RadioButton radioButton = group.findViewById(checkedId);
            int i = group.indexOfChild(radioButton);
            updateBusiness.setIcon(String.valueOf(i));
        });

        // 获取所有项目数据
        Type ProjectType = new TypeToken<Result<List<ProjectSimpleVO>>>() {}.getType();
        OkHttpUtils.getInstance().get(this, RequestEnum.GET_ME_PROJECT, ProjectType, false, (Consumer<List<ProjectSimpleVO>>) projectList -> this.projectList = projectList);
    }

    /**
     * 获取协作人列表
     */
    private void initPersonList() {
        if (ObjectUtil.isNotEmpty(updateBusiness) && updateBusiness.getProjectId() != null) {
            Type type = new TypeToken<Result<List<CustomerBusinessSimpleVO>>>() {}.getType();
            String url = OkHttpUtils.BASE_URL + "/api/v1/business/customer/get/customer/list/" + updateBusiness.getId();
            OkHttpUtils.getInstance().get(this, url, type, true, (Consumer<List<CustomerBusinessSimpleVO>>) voList -> {
                runOnUiThread(() -> {
                    Gson gson = new Gson();
                    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
                    recyclerView.setLayoutManager(layoutManager);
                    ListFriendCollaborationAdapter listFriendCollaborationAdapter = new ListFriendCollaborationAdapter(this, voList);
                    listFriendCollaborationAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.AlphaIn);
                    listFriendCollaborationAdapter.setOnItemClickListener((baseQuickAdapter, view1, i) -> {
                        Intent intent = new Intent(this, ProjectPersonInfoActivity.class);
                        intent.putExtra("isBusiness", true);
                        intent.putExtra("info", gson.toJson(voList.get(i)));
                        intent.putExtra("businessId", updateBusiness.getId());
                        startActivity(intent);
                    });
                    recyclerView.setAdapter(listFriendCollaborationAdapter);
                });
            });
        }
    }



    /**
     * 显示添加成员对话框，添加项目成员到待办，显示对话框
     */
    private void showAddPersonDialog(Integer projectId) {
        LoadingDialog loadingDialog = WidgetUtils.getLoadingDialog(this);
        loadingDialog.show();
        // 1.获取项目成员列表
        getProjectCustomerList(projectId, customerList -> {
            // 2.获取获取待办成员ids
            getBusinessCustomerIds(customerIds -> {
                runOnUiThread(() -> {
                    loadingDialog.dismiss();
                    // 构建底部对话框
                    BottomSheetDialog dialog = new BottomSheetDialog(this, R.style.bottom_sheet_dialog);
                    dialog.setContentView(R.layout.select_person_bottom_dialog);

                    // 顶部右侧按钮点击隐藏
                    CircleImageView circleImageView = dialog.findViewById(R.id.hide_img_view);
                    circleImageView.setOnClickListener(v -> dialog.dismiss());

                    // 获取底部确定按钮
                    Button addEnterBtn = dialog.findViewById(R.id.add_enter_btn);

                    // 协作人适配器
                    RecyclerView friendRecycleView = dialog.findViewById(R.id.recycler_view);
                    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
                    friendRecycleView.setLayoutManager(layoutManager);

                    // 记录用户选中的id
                    final List<Long>[] selectFriendIds = new List[]{new ArrayList<>()};
                    ListSelectFriendAdapter listFriendAdapter = new ListSelectFriendAdapter(this, customerList, customerIds, friendIds -> {
                        addEnterBtn.setText("确定 (" + friendIds.size() + ")");
                        addEnterBtn.setEnabled(friendIds.size() > 0);
                        selectFriendIds[0] = friendIds;
                    });
                    addEnterBtn.setOnClickListener(v -> sendAddFriendInBusiness(selectFriendIds[0], dialog));

                    listFriendAdapter.setItemAnimation(BaseQuickAdapter.AnimationType.AlphaIn);
                    friendRecycleView.setAdapter(listFriendAdapter);
                    dialog.show();
                });
            });
        });
    }

    /**
     * 发送邀请好友进入待办请求
     *
     * @param selectFriendId 好友ids
     * @param dialog         对话框
     */
    private void sendAddFriendInBusiness(List<Long> selectFriendId, BottomSheetDialog dialog) {
        Type type = new TypeToken<Result<Integer>>() {}.getType();
        InvitationFriendBusinessParam param = new InvitationFriendBusinessParam();
        param.setBusinessId(updateBusiness.getId());
        param.setCustomerIdList(selectFriendId);

        OkHttpUtils.getInstance().post(this, RequestEnum.ADD_FRIEND_TO_BUSINESS, type, param, true, (Consumer<Integer>) errorNum -> {
            runOnUiThread(() -> {
                if (errorNum == 0) {
                    XToast.success(this, "邀请成功").show();
                } else {
                    XToast.warning(this, "成功" + (selectFriendId.size() - errorNum) + "条，失败" + errorNum + "条").show();
                }
                dialog.dismiss();
                // 重新获取项目成员列表
                initPersonList();
            });
        });
    }

    /**
     * 获取项目成员ids
     *
     * @param consumer 回调接口
     */
    private void getBusinessCustomerIds(Consumer<List<Long>> consumer) {
        Type type = new TypeToken<Result<List<Long>>>() {
        }.getType();
        String url = OkHttpUtils.BASE_URL + "/api/v1/business/customer/customer/ids/" + updateBusiness.getId();
        OkHttpUtils.getInstance().get(this, url, type, false, (Consumer<List<Long>>) customerIds -> {
            runOnUiThread(() -> consumer.accept(customerIds));
        });
    }

    /**
     * 获取项目成员列表
     *
     * @param projectId 项目id
     * @param consumer  获取到数据，回到接口
     */
    private void getProjectCustomerList(Integer projectId, Consumer<List<FriendListVo>> consumer) {
        Type type = new TypeToken<Result<List<FriendListVo>>>() {
        }.getType();
        String url = OkHttpUtils.BASE_URL + "/api/v1/project/customer/get/customer/list/key/" + projectId;
        OkHttpUtils.getInstance().get(this, url, type, false, (Consumer<List<FriendListVo>>) voList -> {
            runOnUiThread(() -> consumer.accept(voList));
        });
    }

    private void initView() {
        TitleBar titleBar = findViewById(R.id.title_bar);
        titleBar.setTitle("更新待办信息");
        titleBar.addAction(new TitleBar.TextAction("更新") {
            @Override
            public void performAction(View view) {
                updateTodo(true);
            }
        });
        titleBar.setLeftClickListener(v -> finish());
        leftDateWeekText = findViewById(R.id.left_date_week_text);
        leftDateText = findViewById(R.id.left_date_text);
        rightDateWeekText = findViewById(R.id.right_date_week_text);
        rightDateText = findViewById(R.id.right_date_text);

        leftDateWeekText.setOnClickListener(v -> chooseLeftData());
        leftDateText.setOnClickListener(v -> chooseLeftData());
        rightDateWeekText.setOnClickListener(v -> chooseRightData());
        rightDateText.setOnClickListener(v -> chooseRightData());

        remindLayout = findViewById(R.id.time_layout);
        remindLayout.setOnClickListener(v -> setRemindDate());


        remindText = findViewById(R.id.remind_text);
        radioGroup = findViewById(R.id.radio_group);
        Button addButton = findViewById(R.id.add_btn);
        addButton.setVisibility(View.GONE);
        addButton.setText("更新待办");

        titleEdit = findViewById(R.id.title_edit);
        remarkEdit = findViewById(R.id.remark_edit);

        projectLayout = findViewById(R.id.project_layout);
        projectText = findViewById(R.id.project_text);
        projectLayout.setOnClickListener(view -> XToast.info(this, "无法修改绑定项目").show());
        finishLayout = findViewById(R.id.finish_layout);
        finishText = findViewById(R.id.finish_text);
        finishLayout.setOnClickListener(v -> setFinishTime());
        iconRightImg = findViewById(R.id.icon_right_img);
        addPersonLayout = findViewById(R.id.add_person_layout);
        personListLayout = findViewById(R.id.person_list_layout);
        recyclerView = findViewById(R.id.recycler_view);
    }


    /**
     * 更新项目信息
     */
    private void updateTodo(boolean isFinish) {
        if (startDate.compareTo(endDate) > 0) {
            new MaterialDialog.Builder(this).iconRes(R.drawable.icon_info).title(R.string.hint).content("结束日期不能小于开始日期").positiveText(R.string.yes).show();
            return;
        }
        if (StrUtil.hasBlank(titleEdit.getText().toString())) {
            new MaterialDialog.Builder(this).iconRes(R.drawable.icon_info).title(R.string.hint).content("待办名称不可为空").positiveText(R.string.yes).show();
            return;
        }
        updateBusiness.setTitle(titleEdit.getText().toString());
        updateBusiness.setRemark(remarkEdit.getText().toString());
        updateBusiness.setStartTime(canalSdf.format(startDate.getTime()));
        updateBusiness.setEndTime(canalSdf.format(endDate.getTime()));
        Type type = new TypeToken<Result<Business>>() {
        }.getType();
        OkHttpUtils.getInstance().put(UpdateTodoActivity.this, RequestEnum.ADD_BUSINESS, type, updateBusiness, true, (Consumer<Business>) business -> {
            if (business.getCreateTime() != null) {
                if (isFinish) {
                    runOnUiThread(() ->
                            new MaterialDialog.Builder(this).iconRes(R.drawable.icon_success).title(R.string.success).content("待办任务修改成功").positiveText(R.string.yes).onPositive((dialog, which) -> finish()).show()
                    );
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 获取协作人列表
        initPersonList();
    }

    /**
     * 弹出日期时间选择框，用户输入提醒时间
     */
    private void setRemindDate() {
        new CardDatePickerDialog.Builder(this).setTitle("设置提醒时间")
                .setMinTime(System.currentTimeMillis() + 60000) // 设置最短提醒时间在1分钟后
                .setMaxTime(System.currentTimeMillis() + (6 * 30 * 24 * 60 * 60 * 1000L))
                .showBackNow(false) //不显示回到此刻
                .showFocusDateInfo(true) // 显示选中日期信息
                .setThemeColor(getColor(R.color.main)) //设置主题色
                .setBackGroundModel(CardDatePickerDialog.STACK) // 设置顶部圆角
                .setPickerLayout(R.layout.layout_date_picker_segmentation) // 自定义选择格式
                .setLabelText("", "", "", "点", "分", "")
                .setOnChoose("确定", aLong -> {
                    Instant instant = Instant.ofEpochMilli(aLong);
                    LocalDateTime date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
                    List<Integer> remindTimeList = new ArrayList<>(6);
                    remindTimeList.add(date.getYear());
                    remindTimeList.add(date.getMonthValue());
                    remindTimeList.add(date.getDayOfMonth());
                    remindTimeList.add(date.getHour());
                    remindTimeList.add(date.getMinute());
                    remindTimeList.add(date.getSecond());
                    updateBusiness.setRemindTime(remindTimeList);
                    if (date.getYear() == LocalDateTime.now().getYear()) {
                        remindText.setText(LocalDateTimeUtil.format(date, "MM月dd日 HH:mm"));
                    } else {
                        remindText.setText(LocalDateTimeUtil.format(date, DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                    }

                    return null;
                }).setOnCancel("不提醒", () -> {
                    updateBusiness.setRemindTime(null);
                    remindText.setText(R.string.no_remind);
                    return null;
                }).build().show();
    }

    private void setFinishTime() {
        long defaultTime = updateBusiness.getFinishTime().atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
        new CardDatePickerDialog.Builder(this).setTitle("设置完成时间")
                .showBackNow(false) //不显示回到此刻
                .showFocusDateInfo(true) // 显示选中日期信息
                .setThemeColor(getColor(R.color.main)) //设置主题色
                .setBackGroundModel(CardDatePickerDialog.STACK) // 设置顶部圆角
                .setPickerLayout(R.layout.layout_date_picker_segmentation) // 自定义选择格式
                .setDefaultTime(defaultTime)
                .setLabelText("", "", "", "点", "分", "")
                .setOnChoose("确定", aLong -> {
                    Instant instant = Instant.ofEpochMilli(aLong);
                    LocalDateTime date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
                    List<Integer> finishTimeList = new ArrayList<>(6);
                    finishTimeList.add(date.getYear());
                    finishTimeList.add(date.getMonthValue());
                    finishTimeList.add(date.getDayOfMonth());
                    finishTimeList.add(date.getHour());
                    finishTimeList.add(date.getMinute());
                    finishTimeList.add(date.getSecond());
                    updateBusiness.setFinishTime(finishTimeList);
                    if (date.getYear() == LocalDateTime.now().getYear()) {
                        finishText.setText(LocalDateTimeUtil.format(date, "MM月dd日 HH:mm"));
                    } else {
                        finishText.setText(LocalDateTimeUtil.format(date, DatePattern.NORM_DATETIME_MINUTE_PATTERN));
                    }
                    updateTodo(false);
                    return null;
                }).setOnCancel("取消", () -> {
                    return null;
                }).build().show();
    }

    private void chooseLeftData() {
        showDatePickerDialog(UpdateTodoActivity.this, 0, leftDateText, leftDateWeekText, startDate);
    }

    private void chooseRightData() {
        showDatePickerDialog(UpdateTodoActivity.this, 1, rightDateText, rightDateWeekText, endDate);
    }

    /**
     * 显示系统日期框
     *
     * @param context  环境上下文
     * @param weekText 上侧显示周几的
     * @param dataText 具体日期
     * @param calendar 日历类
     * @param m        0开始 1结束时间
     */
    public void showDatePickerDialog(Context context, int m, final TextView dataText, final TextView weekText, Calendar calendar) {
        DatePickerDialog datePickerDialog = new DatePickerDialog(context, com.xuexiang.xui.R.style.XUITheme_AlertDialog, (view, year, month, day) -> {
            Calendar calendar1 = Calendar.getInstance();
            calendar1.set(year, month, day);
            dataText.setText(String.format(Locale.getDefault(), "%d月%d日", (month + 1), day));
            weekText.setText(CalendarUtils.getWeek(calendar1));
            if (m == 0) {
                if (calendar1.compareTo(endDate) > 0) {
                    XToast.normal(UpdateTodoActivity.this, R.string.start_lg_end).show();
                }
                startDate = calendar1;
            } else {
                if (calendar1.compareTo(startDate) < 0) {
                    XToast.normal(UpdateTodoActivity.this, R.string.end_ge_start).show();
                }
                endDate = calendar1;
            }

            if (startDate != null && endDate != null) {
                long differenceInMillis = Math.abs(endDate.getTimeInMillis() - startDate.getTimeInMillis());
                int differenceInDays = (int) (differenceInMillis / (24 * 60 * 60 * 1000));
                if (differenceInDays == 0) {
                    iconRightImg.setText("24小时");
                } else {
                    iconRightImg.setText(String.format(Locale.CHINA, "%d天", differenceInDays + 1));
                }
            }
        }, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
        datePickerDialog.show();
    }
}